import 'dart:math';
import 'dart:ui' as ui;
import 'dart:ui';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class UserAbilityCobwebView extends CustomPainter{

  ///多边形几个边
  int sideNum = 6;

  ///默认几层多边形
  int layerNum = 4;

  ///view 的中心点
  double viewCenterX;
  double viewCenterY;

  ///半径，最大的半径
  double maxRadius;
  double whiteCircleRadius;
  double pointRadius;
  final double circleAngle = 360;

  double eachRadius;
  double eachAngle;

  Color lineColor;
  Color layerColor;
  Color pointColor;
  Color bgColor;

  List<double> scores;
  List<String> skills;
  int maxScore;

  Paint mPaint;
  Path mPath;
  Paint mLayerPaint;
  Paint pointPaint;
  Paint bgPaint;

  UserAbilityCobwebView(
      {
        @required List<double> scores,
        this.skills,
        this.maxScore = 100,
        int layerNum = 4,
        double maxRadius = 0,
        this.pointRadius = 2,
        Color lineColor = Colors.white,
        Color layerColor = const Color(0x88ffdd00),
        Color pointColor = const Color(0xddffdd00),
        Color bgColor = const Color(0x66f89800),
      }) {
    this.scores = scores;
    this.sideNum = scores.length;
    this.layerNum = layerNum;
    this.lineColor = lineColor;
    this.layerColor = layerColor;
    this.maxRadius = maxRadius;
    mPaint = new Paint();
    mPaint.color = lineColor;
    mPaint.isAntiAlias = true;
    mPaint.style = PaintingStyle.stroke;
    mPath = new Path();

    mLayerPaint = new Paint();
    mLayerPaint.color = layerColor;
    mLayerPaint.isAntiAlias = true;
    mLayerPaint.style = PaintingStyle.fill;

    pointPaint = new Paint();
    pointPaint.color = pointColor;
    pointPaint.isAntiAlias = true;
    pointPaint.style = PaintingStyle.fill;
    pointPaint.strokeWidth = 3;

    bgPaint = new Paint();
    bgPaint.color = bgColor;
    bgPaint.isAntiAlias = true;
    bgPaint.style = PaintingStyle.fill;
  }

  @override
  void paint(Canvas canvas, Size size) {
    viewCenterX = size.width / 2;
    viewCenterY = size.height / 2;
    if(maxRadius == 0){
      if (viewCenterX > viewCenterY) {
        maxRadius = viewCenterY/2;
      } else {
        maxRadius = viewCenterX/2;
      }
    }

    eachAngle = circleAngle / sideNum;
    whiteCircleRadius = maxRadius * sin(degToRadians(eachAngle));
    canvas.save();
    drawWhiteCircleBg(canvas);
    drawBg(canvas);
    drawPolygon(canvas);
    drawMaskLayer(canvas);
    drawPoint(canvas);
    drawTitle(canvas);
    canvas.restore();
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
//    return oldDelegate != this;
    return true;
  }

  ///绘制圆形轨迹
  void drawWhiteCircleBg(Canvas canvas) {
    double eachRadius;
    for (int i = 0; i < 3; i++) {
      if(i == 0){
        eachRadius = whiteCircleRadius - 1;
      } else if(i == 1){
        eachRadius = maxRadius * 1.6;
      } else {
        eachRadius = 0.7 * viewCenterX;
      }
      canvas.drawCircle(Offset(viewCenterX, viewCenterY), eachRadius, mPaint);
    }
  }

  ///绘制背景
  void drawBg(Canvas canvas) {
    mPath.reset();
    for (int i = 0; i < sideNum; i++) {
      double value = 1;
      double x = viewCenterX + maxRadius * cos(degToRadians(eachAngle * i -90)) * value;
      double y = viewCenterY + maxRadius * sin(degToRadians(eachAngle * i -90)) * value;
      if (i == 0) {
        mPath.moveTo(x, y);
      } else {
        mPath.lineTo(x, y);
      }
    }
    mPath.close();
    canvas.drawPath(mPath, bgPaint);
  }

  ///绘制边线
  void drawPolygon(Canvas canvas) {
    ///每个角的度数
    eachAngle = circleAngle / sideNum;

    ///找好所有的顶点，连接起来即可
    for (int i = 0; i < layerNum; i++) {
      mPath.reset();
      eachRadius = maxRadius / layerNum * (i + 1);

      for (int j = 0; j < sideNum + 1; j++) {
        if (j == 0) {
          mPath.moveTo(viewCenterX, viewCenterY + eachRadius);
        } else {
          double x = viewCenterX + eachRadius * sin(degToRadians(eachAngle * j));
          double y = viewCenterY + eachRadius * cos(degToRadians(eachAngle * j));
          mPath.lineTo(x, y);
        }
      }
      mPath.close();
      canvas.drawPath(mPath, mPaint);
    }
    drawLineLinkPoint(canvas, eachAngle, eachRadius);
  }

  ///绘制轴线
  void drawLineLinkPoint(Canvas canvas, double eachAngle, double eachRadius) {
    mPath.reset();
    for (int i = 0; i < sideNum; i++) {
      mPath.moveTo(viewCenterX, viewCenterY);
      double x = viewCenterX + eachRadius * sin(degToRadians(eachAngle * i));
      double y = viewCenterY + eachRadius * cos(degToRadians(eachAngle * i));
      mPath.lineTo(x, y);
      mPath.close();
      canvas.drawPath(mPath, mPaint);
    }
  }

  ///绘制覆盖区域
  void drawMaskLayer(Canvas canvas) {
    mPath.reset();
    for (int i = 0; i < sideNum; i++) {
      double value = scores.elementAt(i)/maxScore;
      double x = viewCenterX + maxRadius * cos(degToRadians(eachAngle * i -90)) * value;
      double y = viewCenterY + maxRadius * sin(degToRadians(eachAngle * i -90)) * value;
      if (i == 0) {
//        mPath.moveTo(viewCenterX, viewCenterY - maxRadius*value);
        mPath.moveTo(x, y);
      } else {
        mPath.lineTo(x, y);
      }
    }
    mPath.close();
    canvas.drawPath(mPath, mLayerPaint);
  }

  ///绘制点
  void drawPoint(Canvas canvas) {
    List<Offset> points = List<Offset>();
    for (int i = 0; i < sideNum; i++) {
      double value = scores.elementAt(i)/maxScore;
      double x = viewCenterX + maxRadius * cos(degToRadians(eachAngle * i -90)) * value;
      double y = viewCenterY + maxRadius * sin(degToRadians(eachAngle * i -90)) * value;
      points.add(Offset(x, y));
      canvas.drawCircle(Offset(x, y), pointRadius, pointPaint);
    }
  }

  ///绘制文字
  void drawTitle(Canvas canvas) {
    double textHeight = 10;
    double textPadding = 10;
    double textLength;
    for (int i = 0; i < sideNum; i++) {
      textLength = skills[i].length * textHeight;

      double x = viewCenterX + maxRadius * cos(degToRadians(eachAngle * i - 90));
      double y = viewCenterY + maxRadius * sin(degToRadians(eachAngle * i - 90));
      if(x < viewCenterX){
        x = x - (textLength + textPadding);
      } else if(x == viewCenterX){
        x = x - textLength/2;
      } else {
        x = x + (textPadding);
      }

      if(y == viewCenterY - maxRadius){//上
        y = y - (textHeight + textPadding);
      } else if(y == viewCenterY + maxRadius){//下
        y = y + textPadding;
      } else {
        y = y - textHeight/2;
      }
      canvas.save();
      drawText(canvas, skills[i], Offset(x, y),
          fontSize: textHeight, maxWith: 5*textHeight);
      canvas.restore();
    }
  }


  //绘制文字
  drawText(Canvas canvas, String text, Offset offset,
      {Color color = Colors.white,
        double maxWith = 100,
        double fontSize,
        String fontFamily,
        TextAlign textAlign = TextAlign.center,
//        FontWeight fontWeight = FontWeight.bold
      }) {
    //  绘制文字
    var paragraphBuilder = ui.ParagraphBuilder(
      ui.ParagraphStyle(
        fontFamily: fontFamily,
        textAlign: textAlign,
        fontSize: fontSize,
//        fontWeight: fontWeight,
      ),
    );
    paragraphBuilder.pushStyle(
        ui.TextStyle(color: color, textBaseline: ui.TextBaseline.alphabetic));
    paragraphBuilder.addText(text);
    var paragraph = paragraphBuilder.build();
    paragraph.layout(ui.ParagraphConstraints(width: maxWith));
    canvas.drawParagraph(paragraph, Offset(offset.dx, offset.dy));
  }

  //角度转弧度
  num degToRadians(num deg) => deg * (pi / 180.0);
  //弧度转角度
  num radianToDeg(num rad) => rad * (180.0 / pi);

}